
package com.oahc.magicdefender.screen;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.input.GestureDetector;
import com.badlogic.gdx.input.GestureDetector.GestureListener;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.oahc.magicdefender.MainGame;
import com.oahc.magicdefender.data.EnemyAniData;
import com.oahc.magicdefender.manager.Arrow;
import com.oahc.magicdefender.manager.ArrowGroup;
import com.oahc.magicdefender.manager.Enemy;
import com.oahc.magicdefender.manager.EnemyGroup;
import com.oahc.magicdefender.util.FontHelper;
import com.oahc.magicdefender.util.MDConfig;
import com.oahc.magicdefender.xml.plist.PListXMLHandler;
import com.oahc.magicdefender.xml.plist.PListXMLParser;
import com.oahc.magicdefender.xml.plist.domain.Dict;
import com.oahc.magicdefender.xml.plist.domain.PList;
import com.oahc.magicdefender.xml.plist.domain.PListObject;

public class GameScreen extends AbstractScreen implements GestureListener {

    HashMap<String, EnemyAniData> enemyAniDatas = new HashMap<String, EnemyAniData>();

    public GameScreen(MainGame game) {
        super(game);

        long startime=System.currentTimeMillis();
        PListXMLParser parser = new PListXMLParser();
        PListXMLHandler handler = new PListXMLHandler();
        parser.setHandler(handler);
        try {
            parser.parse(Gdx.files.internal("always/plist/monster1.plist").read());
            PList pList = ((PListXMLHandler)parser.getHandler()).getPlist();
            Dict rDict = (Dict)pList.getRootElement();
            Map<String, PListObject> dataMap = rDict.getConfigMap();

            Set<String> keys = dataMap.keySet();
            for (String key : keys) {

                if ("frames".equals(key)) {
                    Dict tDict = (Dict)dataMap.get(key);
                    Map<String, PListObject> tdataMap = tDict.getConfigMap();
                    for (String tKey : tdataMap.keySet()) {
                        Dict t2Dict = (Dict)tdataMap.get(tKey);
                        EnemyAniData enemyAniData = new EnemyAniData(t2Dict.getConfigMap());
                        enemyAniDatas.put(tKey, enemyAniData);
                    }
                }
            }

        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            Gdx.app.error("MD", e.getMessage());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            Gdx.app.error("MD", e.getMessage());
        }
        

        Gdx.app.log("MD","plist parse :"+(System.currentTimeMillis()-startime));
    }

    @Override
    public void render(float delta) {
        super.render(delta);
        spriteBatch.begin();

        for (Actor actor : actorsManager) {
            if (!pause) {
                actor.act(delta);
            }
            actor.draw(spriteBatch, 1);
        }

        arrowGroup.draw(spriteBatch, 1);
        enemyGroup.draw(spriteBatch, 1);
        
        FontHelper.getInstance().drawFPS(spriteBatch);
        spriteBatch.end();
        if (!pause) {
            arrowGroup.act(delta);
            enemyGroup.act(delta);
        }

    }

    @Override
    public void resize(int width, int height) {
        // TODO Auto-generated method stub

    }

    ArrayList<Actor> actorsManager = new ArrayList<Actor>();

    Image arrowSlotImage, arrowtImage;

    TextureRegion arrowRegion;

    private SpriteBatch spriteBatch;

    ArrowGroup arrowGroup;
    EnemyGroup enemyGroup;
    
    Texture monster1Texture;

    @Override
    public void show() {
        enemyGroup=new EnemyGroup();
        arrowGroup = new ArrowGroup();
        spriteBatch = new SpriteBatch();
        // 背景图
        Texture bgTexture = new Texture(Gdx.files.internal("game/bg_lv0.jpg"));
        TextureRegion bgRegion = new TextureRegion(bgTexture, MDConfig.IMG_WIDTH,
                MDConfig.IMG_HEIGHT);
        Image imageBg = new Image(bgRegion);
        // 将图片缩放至屏幕大小
        imageBg.setWidth(Gdx.graphics.getWidth());
        imageBg.setHeight(Gdx.graphics.getHeight());
        actorsManager.add(imageBg);
        // 弓箭槽
        Texture arrowSlotTexture = new Texture(Gdx.files.internal("game/bow_normal.png"));
        TextureRegion arrowSlotRegion = new TextureRegion(arrowSlotTexture, 90, 145);
        arrowSlotImage = new Image(arrowSlotRegion);
        arrowSlotImage.setSize(arrowSlotImage.getWidth() * MDConfig.getXScale(),
                arrowSlotImage.getHeight() * MDConfig.getYScale());
        float arrowSlotX = MDConfig.exchangeY(MDConfig.ARROW_SLOT_INIT_X);
        float arrowSlotY = MDConfig.exchangeY(MDConfig.ARROW_SLOT_INIT_Y);
        arrowSlotImage.setPosition(arrowSlotX, arrowSlotY);
        // 设置旋转的中心点
        arrowSlotImage.setOrigin(-arrowSlotX, arrowSlotImage.getHeight() / 2);
        actorsManager.add(arrowSlotImage);

        // 默认弓箭
        Texture arrowTexture = new Texture(Gdx.files.internal("game/arrow_normal.png"));
        arrowRegion = new TextureRegion(arrowTexture, 85, 10);
        arrowtImage = new Image(arrowRegion);
        arrowtImage.setSize(arrowtImage.getWidth() * MDConfig.getXScale(), arrowtImage.getHeight()
                * MDConfig.getYScale());
        arrowtImage.setPosition(0, arrowSlotY + arrowSlotImage.getHeight() / 2);
        actorsManager.add(arrowtImage);

        // 怪物图
        monster1Texture= new Texture(Gdx.files.internal("always/plist/monster1.png"));
     
        addEnemy();
        Gdx.input.setInputProcessor(new GestureDetector(this));

    }

    private void addEnemy(){
        Enemy enemy=new Enemy(monster1Texture, enemyAniDatas);
        enemy.setPosition(800, 500);
        enemyGroup.addActor(enemy);
    }
    
    
    private Arrow getShootArrow(float degrees2) {
        Arrow arrowtImage = new Arrow(arrowRegion);
        arrowtImage.setSize(arrowtImage.getWidth() * MDConfig.getXScale(), arrowtImage.getHeight()
                * MDConfig.getYScale());
        arrowtImage.setPosition(0,
                MDConfig.exchangeY(MDConfig.ARROW_SLOT_INIT_Y) + arrowSlotImage.getHeight() / 2);
        arrowtImage.setOrigin(0, arrowtImage.getHeight() / 2);
        arrowtImage.rotate(degrees2);
        arrowtImage.setK((float)Math.tan(Math.toRadians(degrees2)));
        return arrowtImage;
    }

    float totaltime = 0f;

    float degrees;

    private void shootArrow(float deltatime, float degrees2) {
        totaltime += deltatime;
        // if (totaltime > 0.5f) {
        // totaltime = 0;
        Arrow image = getShootArrow(degrees2);

        arrowGroup.addActor(image);
        // }
        
        addEnemy();
    }

    private void changeArrowSlot(float x, float y) {

        Gdx.app.log("MD", "x=" + x + ",y=" + y + ",gh=" + Gdx.graphics.getHeight() + ",ay="
                + arrowtImage.getY() + ",ax=" + arrowSlotImage.getX());
        if (pause) {
            return;
        }

        // 触摸事件得到的坐标是以左上角为（0,0）需要转换成Libgdx坐标系
        float dy = Gdx.graphics.getHeight() - y - arrowSlotImage.getY()
                - arrowSlotImage.getHeight() / 2;
        float dx = x;
        degrees = (float)Math.toDegrees(Math.atan(dy / dx));
        Gdx.app.log("MD", "degrees :" + degrees);

        arrowSlotImage.setRotation(degrees);
        arrowtImage.setRotation(degrees);

        shootArrow(0, degrees);
    }

    @Override
    public void hide() {
        // TODO Auto-generated method stub
        // FontHelper.clearInstance();
        actorsManager.clear();
    }

    boolean pause = false;

    @Override
    public void pause() {
        FontHelper.clearInstance();
        pause = true;
        Gdx.app.log("MD", "GameScreen pause");
    }

    @Override
    public void resume() {
        // TODO Auto-generated method stub
        pause = false;
        Gdx.app.log("MD", "GameScreen resume");
    }

    @Override
    public void dispose() {
        // TODO Auto-generated method stub

    }

    @Override
    public void onBackPressed() {
        // TODO Auto-generated method stub
        // getMainGame().setScreen(new StartScreen(getMainGame()));
        this.pause();
        Gdx.app.log("MD", "GameScreen onBackPressed");
    }

    @Override
    public boolean touchDown(float x, float y, int pointer, int button) {
        Gdx.app.log("MD", "touchDown");
        changeArrowSlot(x, y);
        return false;
    }

    @Override
    public boolean tap(float x, float y, int count, int button) {
        Gdx.app.log("MD", "tap");
        // changeArrowSlot(x, y);
        return false;
    }

    @Override
    public boolean longPress(float x, float y) {
        Gdx.app.log("MD", "longPress");
        return false;
    }

    @Override
    public boolean fling(float velocityX, float velocityY, int button) {
        Gdx.app.log("MD", "fling");
        return false;
    }

    @Override
    public boolean pan(float x, float y, float deltaX, float deltaY) {
        Gdx.app.log("MD", "pan");
        changeArrowSlot(x, y);
        return false;
    }

    @Override
    public boolean panStop(float x, float y, int pointer, int button) {
        Gdx.app.log("MD", "panStop");
        return false;
    }

    @Override
    public boolean zoom(float initialDistance, float distance) {
        Gdx.app.log("MD", "zoom");
        return false;
    }

    @Override
    public boolean pinch(Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1,
            Vector2 pointer2) {
        Gdx.app.log("MD", "pinch");
        return false;
    }

}
